#pragma once

#include "symboleditor_global.h"
#include "core/editormanager/idocument.h"
#include "xdl/symbol.h"

#include <QMap>
#include <QAtomicInteger>

namespace SymbolEditor
{

    // TODO: investigate passing item by const reference and implement cow on item's data?
    class Document : public IDocument
    {
        Q_OBJECT
    public:

        explicit Document(QObject *parent = nullptr);

        bool load(QString *errorString, const QString &fileName);

        QString symbolName() const;
        QString symbolLabel() const;
        const Item *item(quint64 id) const;
        QList<quint64> itemIdList() const;

        quint64 addItem(Item *item, quint64 id = 0);
        quint64 addItem(ItemType type, quint64 id = 0);
        quint64 cloneItem(quint64 id, quint64 cloneId = 0);
        void removeItem(quint64 id);
        void setItemProperty(quint64 itemId, PropertyId propertyId, const QVariant &value);
        QVariant itemProperty(quint64 itemId, PropertyId propertyId) const;
        QString friendlyItemPropertyName(quint64 itemId, PropertyId propertyId);
        QString friendlyItemTypeName(quint64 itemId);

        QList<quint64> itemStack() const;
        void stackItemBefore(quint64 itemId, quint64 referenceId);

    signals:
        void itemAdded(quint64 id, const Item *item);
        void itemChanged(quint64 id, const Item *item);
        void itemPropertyChanged(quint64 itemId, quint64 propertyId, const QVariant &value);
        void itemRemoved(quint64 id);

        void itemGroupCreated(quint64 id, const ItemGroup *group);
        void itemGroupDestroyed(quint64 id, const ItemGroup *group); // TBD: children list
        void itemParentChanged(quint64 id, const Item *item); /// TBD: parent changes (not grouping)

        void itemStackReordered(quint64 itemId, quint64 beforeId);

    private:
        QAtomicInteger<quint64> m_itemIndex;
        QString m_symbolName;
        QString m_symbolLabel;
        QMap<quint64, Item *> m_drawingItemMap;
        QList<quint64> m_itemStack;

        // IDocument interface
    public:
        bool save(QString *errorString, const QString &fileName);
        void render(QPainter *painter);
    };
}
